package com.C1对象及变量的并发访问.S1synchronized同步方法;

/**
 * @Auther: SJZ    2907374717@qq.com
 * @Date: 2019/3/12 23:12
 * @Description:方法内的变量为线程安全
 * 线程安全与非线程安全相关的技术点。非线程安全其实会在多个线程对同一个对象的实例变量进行并发访问产生的。
 * 产生的后果就是“脏读”，也就是取到的数据可能是被更改过的。
 * 而线程安全就是获得实例变量的值是经过同步处理的不会出现脏读现象。
 * <p>
 * 非线程安全问题存在于“实例变量”中，如果是方法内部的私有变量，测则不存在“非线程安全”问题，所得的结果也就是
 * “线程安全”的了
 */
public class A1HimselfPirvateNum {

//private int num=0;
// 如果把上面这个注释放开，把下面的 int num=0;注释掉就会出现“非线程安全”现象。
//两个线程同时访问一个没有同步的方法如果两个线程同时操作业务对象中的实例变量，则有可能出现“非线程安全”
//问题

    //如果要解决这个问题只需在 addI(String usesrname)方法前加 synchronized关键字即可。
    public void addI(String username) {
       int num = 0;//方法内部变量，是私有属性
        if (username.equals("a")) {
            num = 100;
            System.out.println("a set over");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            num = 200;
            System.out.println("b set over");
        }
        System.out.println(username + "num=" + num);
    }


    public static void main(String[] args) {
        A1HimselfPirvateNum a1HimselfPirvateNum= new A1HimselfPirvateNum();
        new ThreadA(a1HimselfPirvateNum).start();
        new ThreadB(a1HimselfPirvateNum).start();
    }

    static class ThreadA extends Thread{
        private A1HimselfPirvateNum numHimself;//
        public ThreadA(A1HimselfPirvateNum a1HimselfPirvateNum){
            super();
            this.numHimself=a1HimselfPirvateNum;
        }
        public void run(){
            super.run();
            numHimself.addI("a");
        }
    }

    static class ThreadB extends Thread{
        private A1HimselfPirvateNum numHimself;//内部私有变量
        public ThreadB(A1HimselfPirvateNum a1HimselfPirvateNum){
            super();
            this.numHimself=a1HimselfPirvateNum;
        }
        public void run(){
            super.run();
            numHimself.addI("b");
        }
    }
}
